package top.oneit.jdownload.controller.item;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import javafx.application.Platform;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.Tooltip;
import javafx.scene.input.MouseEvent;
import org.hibernate.Session;
import org.kordamp.ikonli.javafx.FontIcon;
import top.oneit.jdownload.constants.JConstants;
import top.oneit.jdownload.controller.BaseInitializable;
import top.oneit.jdownload.data.dao.DownloadSaveStatusDao;
import top.oneit.jdownload.data.dao.DownloadingTablePoDao;
import top.oneit.jdownload.data.entity.DownloadFile;
import top.oneit.jdownload.data.entity.DownloadSaveStatus;
import top.oneit.jdownload.data.entity.DownloadingTablePo;
import top.oneit.jdownload.download.DownloadingTask;
import top.oneit.jdownload.service.DownloadTaskService;
import top.oneit.jdownload.stages.HomeStage;
import top.oneit.jdownload.utils.BaseUtils;
import top.oneit.jdownload.utils.StorageUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ActionsItemController extends BaseInitializable {
    private DownloadingTablePo tablePo;

    public ActionsItemController(DownloadingTablePo tablePo) {
        this.tablePo = tablePo;
    }

    @FXML
    private Label stopAndStart, delete;
    private Timer timer;
    private HomeStage homeStage = getStage(HomeStage.class);
    public Integer currentDownloadSize = 0, speed = 0;
    ;
    public boolean isPause, isDelete;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        stopAndStart.setTooltip(new Tooltip("暂停任务"));
        delete.setTooltip(new Tooltip("删除任务"));
        if (JConstants.FILE_STATUS_PAUSE.equals(tablePo.getStatus())) {
            updateIcon(true);
        } else if (JConstants.FILE_STATUS_AWAIT_DOWNLOAD.equals(tablePo.getStatus())) {
            Timer timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    if (stopAndStart.isVisible()) {
                        Platform.runLater(new Runnable() {
                            @Override
                            public void run() {
                                // 创建是等待下载时，直接执行下载
                                updateIcon(false);
                                runDownload();
                            }
                        });
                        timer.cancel();
                    }
                }
            }, 1000, 1000);

        }

        stopAndStart.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                if (BaseUtils.repeatClickChecking("s")) return;
                if (JConstants.FILE_STATUS_PAUSE.equals(tablePo.getStatus())) {//继续
                    runDownload();
                } else if (JConstants.FILE_STATUS_DOWNLOADING.equals(tablePo.getStatus())) {// 暂停
                    stopDownload();
                }
            }
        });


        delete.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                if (BaseUtils.repeatClickChecking("d")) return;
                if (!isDelete) {
                    if (isDelete) {
                        return;
                    }
                    isDelete = true;
                    deleteDownload();
                }
            }
        });
    }

    private void deleteDownload() {
        DownloadSaveStatusDao.deleteByDownloadingTablePo(tablePo);
        Session session = getSession();
        session.beginTransaction();
        // 删除
        session.createQuery("delete from DownloadingTablePo where downloadFile=:df")
                .setParameter("df", tablePo.getDownloadFile()).executeUpdate();

        DownloadFile downloadFile = tablePo.getDownloadFile();
        downloadFile.setStatus(JConstants.FILE_STATUS_DELETE);
        session.update(downloadFile);
        session.getTransaction().commit();
        // 刷新表格
        homeStage.refreshTable();
        File file = new File(downloadFile.getSavePath() + File.separator + downloadFile.getSaveName() + ".j");
        if (file.exists()) {
            file.delete();
        }
    }

    private void stopDownload() {
        isPause = true;
        updateIcon(true);
        tablePo.setStatus(JConstants.FILE_STATUS_PAUSE);
        DownloadingTablePoDao.updateStatus(tablePo.getId(), JConstants.FILE_STATUS_PAUSE);
    }

    private void runDownload() {
        isPause = false;
        updateIcon(false);
        tablePo.setStatus(JConstants.FILE_STATUS_DOWNLOADING);// 状态设置为下载
        DownloadingTablePoDao.updateStatus(tablePo.getId(), JConstants.FILE_STATUS_DOWNLOADING);

        List<DownloadSaveStatus> byDownloadingTablePo = DownloadSaveStatusDao.getByDownloadingTablePo(tablePo);
        DownloadFile downloadFile = tablePo.getDownloadFile();
        if (CollectionUtil.isEmpty(byDownloadingTablePo)) {
            byDownloadingTablePo = new ArrayList<>();
            int threadSize = downloadFile.getSize() / downloadFile.getThreadNumber();
            int num = downloadFile.getThreadNumber();
            for (int i = 0; i < num; i++) {
                DownloadSaveStatus status = new DownloadSaveStatus();
                status.setStatus(JConstants.FILE_STATUS_NOT_FINISH);
                status.setDownloadLength(threadSize);
                status.setStartPosition(i * threadSize);
                if (i == (num - 1)) {// 加上求余
                    int surplus = downloadFile.getSize() % num;
                    status.setDownloadLength(threadSize + surplus);
                } else {
                    status.setDownloadLength(threadSize);
                }
                status.setCurrentPosition(status.getStartPosition());
                status.setDownloadingTablePo(tablePo);
                byDownloadingTablePo.add(status);
            }
            DownloadSaveStatusDao.save(byDownloadingTablePo);
        }

        File file = new File(downloadFile.getSavePath() + File.separator + downloadFile.getSaveName() + ".j");
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                Assert.isNull(e, "创建下载文件失败！");
            }
        }

        // 开启定时
        timer = new Timer();
        int index = getIndex(homeStage.downloadingTablePos);
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                if (isDelete || isPause) {
                    timer.cancel();
                    return;
                }
                boolean complete = DownloadTaskService.checkComplete(tablePo, timer);
                if (!complete) {
                    Platform.runLater(new Runnable() {
                        @Override
                        public void run() {
                            homeStage.downloadingTablePos.get(index).getSpeed().setText(StorageUtils.byteToSpeedString(currentDownloadSize-speed));
                            homeStage.downloadingTablePos.get(index).getSurplusStr().setText(StorageUtils.byteToString(downloadFile.getSize() - currentDownloadSize));
                            speed = currentDownloadSize;
                        }
                    });
                    System.out.println(currentDownloadSize);
                }
            }
        }, 1000, 1000);

        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(tablePo.getDownloadFile().getThreadNumber());
        // 执行下载
        for (DownloadSaveStatus status : byDownloadingTablePo) {
            fixedThreadPool.execute(new DownloadingTask(status, this));
        }
    }

    private int getIndex(ObservableList<DownloadingTablePo> downloadingTablePos) {
        for (int i = 0; i < downloadingTablePos.size(); i++) {
            if (downloadingTablePos.get(i).getId().equals(tablePo.getId())) {
                return i;
            }
        }
        return -1;
    }

    /**
     * @param play true: 表示显示播放图标
     */
    private void updateIcon(boolean play) {
        if (play) {
            FontIcon icon = new FontIcon("fa-play-circle-o");
            icon.setIconSize(20);
            stopAndStart.setGraphic(icon);
        } else {
            FontIcon icon = new FontIcon("fa-pause-circle-o");
            icon.setIconSize(20);
            stopAndStart.setGraphic(icon);
        }
    }

    public static void main(String[] args) throws Exception {

    }
}
